package com.dianxin.smartpark.service.park.impl;

import java.util.Date;
import java.util.List;

import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.chinatelecom.response.common.CommonResponseBody;
import com.chinatelecom.response.utils.BeanUtil;
import com.chinatelecom.response.utils.Convert;
import com.chinatelecom.response.utils.ResponseBodyWrapperUtil;
import com.chinatelecom.response.constant.ErrMsgEnum;

import com.chinatelecom.response.utils.StringUtils;
import com.dianxin.acl.api.acl.AclFileRpcService;
import com.dianxin.acl.api.acl.AclUserRpcService;
import com.dianxin.acl.api.dto.SsoUserDTO;
import com.dianxin.acl.api.dto.SysFileDTO;
import com.dianxin.acl.api.qo.SsoUserRpcQO;
import com.dianxin.common.oss.properties.FileUploadResponse;
import com.dianxin.common.oss.util.MinioUtil;
import com.dianxin.device.api.device.SmartParkDeviceRpcService;
import com.dianxin.device.api.device.dto.SmartDeviceDTO;
import com.dianxin.device.api.device.qo.SmartDeviceNoAclRpcQO;
import com.dianxin.smartpark.dao.dataobject.park.*;
import com.dianxin.smartpark.dao.dataobject.visitor.SmartParkVisitor;
import com.dianxin.smartpark.dao.mapper.park.SmartParkAreaMapper;
import com.dianxin.smartpark.dao.mapper.park.SmartParkCarParkParkingMapper;
import com.dianxin.smartpark.dao.mapper.park.SmartParkCarParkingMapper;
import com.dianxin.smartpark.dao.mapper.visitor.SmartParkVisitorMapper;
import com.dianxin.smartpark.dao.qo.park.SmartParkCarParkingQO;
import com.dianxin.smartpark.service.park.SmartParkCarParkParkingService;
import com.dianxin.smartpark.service.park.SmartParkCarParkingService;
import com.dianxin.smartpark.service.vo.park.SmartParkCarParkingVO;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * 停车记录业务层处理
 * 
 * @author chenjiasong
 * @date 2021-08-31
 */
@Service
public class SmartParkCarParkingServiceImpl implements SmartParkCarParkingService
{
    private final static Logger logger = LoggerFactory.getLogger(SmartParkCarParkingServiceImpl.class);
    @Resource
    private SmartParkCarParkingMapper smartParkCarParkingMapper;

    @Resource
    private SmartParkCarParkParkingMapper smartParkCarParkParkingMapper;

    @Resource
    private SmartParkVisitorMapper smartParkVisitorMapper;

    @Resource
    private AclUserRpcService aclUserRpcService;

    @Resource
    private SmartParkAreaMapper smartParkAreaMapper;

    @Resource
    private AclFileRpcService aclFileRpcService;

    @Resource
    private SmartParkDeviceRpcService smartParkDeviceRpcService;

    @Resource
    private MinioUtil minioUtil;


    /**
     * 查询停车记录
     * 
     * @param qo 停车记录
     * @return 停车记录
     */
    @Override
    public CommonResponseBody<SmartParkCarParkingVO> selectSmartParkCarParking(SmartParkCarParkingQO qo)
    {
        if(StringUtils.isNull(qo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkCarParkingExample smartParkCarParkingExample = new SmartParkCarParkingExample();
        SmartParkCarParkingExample.Criteria criteria = smartParkCarParkingExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
        }
        criteria.andIsDeletedEqualTo(0);
        criteria.andIdEqualTo(qo.getId());
        List<SmartParkCarParking> passRecords = smartParkCarParkingMapper.selectByExample(smartParkCarParkingExample);
        return ResponseBodyWrapperUtil.successWrapper(StringUtils.isNotEmpty(passRecords)?passRecords.get(0):null,SmartParkCarParkingVO.class);
    }

    /**
     * 查询停车记录列表
     * 
     * @param qo 停车记录
     * @return 停车记录
     */
    @Override
    public CommonResponseBody<List<SmartParkCarParkingVO>> selectSmartParkCarParkingList(SmartParkCarParkingQO qo)
    {
        SmartParkCarParkingExample smartParkCarParkingExample = new SmartParkCarParkingExample();
        SmartParkCarParkingExample.Criteria criteria = smartParkCarParkingExample.createCriteria();
        SmartParkCarParkingExample.Criteria criteria1 = smartParkCarParkingExample.createCriteria();
        SmartParkCarParkingExample.Criteria criteria2 = smartParkCarParkingExample.createCriteria();
        SmartParkCarParkingExample.Criteria criteria3 = smartParkCarParkingExample.createCriteria();
        if (qo.getTenantId() != null) {
            criteria.andTenantIdEqualTo(qo.getTenantId());
            criteria1.andTenantIdEqualTo(qo.getTenantId());
            criteria2.andTenantIdEqualTo(qo.getTenantId());
            criteria3.andTenantIdEqualTo(qo.getTenantId());
        }
        if (qo.getStatus() != null) {
            criteria.andStatusEqualTo(qo.getStatus());
            criteria1.andStatusEqualTo(qo.getStatus());
            criteria2.andStatusEqualTo(qo.getStatus());
            criteria3.andStatusEqualTo(qo.getStatus());
        }
        if (StringUtils.isNotNull(qo.getCarType())) {
            criteria.andCarTypeEqualTo(qo.getCarType());
            criteria1.andCarTypeEqualTo(qo.getCarType());
            criteria2.andCarTypeEqualTo(qo.getCarType());
            criteria3.andCarTypeEqualTo(qo.getCarType());
        }
        if (StringUtils.isNotEmpty(qo.getSerachText())) {
            criteria.andUserNameLike("%"+qo.getSerachText()+"%");
            criteria1.andPhoneNumLike("%"+qo.getSerachText()+"%");
            criteria2.andIdNumLike("%"+qo.getSerachText()+"%");
            criteria3.andLicensePlateLike("%"+qo.getSerachText()+"%");
        }

        if (StringUtils.isNotNull(qo.getStartTime())) {
            criteria.andOpenTimeGreaterThanOrEqualTo(qo.getStartTime());
            criteria1.andOpenTimeGreaterThanOrEqualTo(qo.getStartTime());
            criteria2.andOpenTimeGreaterThanOrEqualTo(qo.getStartTime());
            criteria3.andOpenTimeGreaterThanOrEqualTo(qo.getStartTime());
        }

        if (StringUtils.isNotNull(qo.getEndTime())) {
            criteria.andOpenTimeLessThanOrEqualTo(qo.getEndTime());
            criteria1.andOpenTimeLessThanOrEqualTo(qo.getEndTime());
            criteria2.andOpenTimeLessThanOrEqualTo(qo.getEndTime());
            criteria3.andOpenTimeLessThanOrEqualTo(qo.getEndTime());
        }
        criteria.andIsDeletedEqualTo(0);
        criteria1.andIsDeletedEqualTo(0);
        criteria2.andIsDeletedEqualTo(0);
        criteria3.andIsDeletedEqualTo(0);
        smartParkCarParkingExample.or(criteria1);
        smartParkCarParkingExample.or(criteria2);
        smartParkCarParkingExample.or(criteria3);
        if (qo.getNeedPage()) {
            smartParkCarParkingExample.setOrderByClause("open_time desc limit " + (qo.getPageIndex() - 1) * qo.getPageSize() + "," + qo.getPageSize());
        } else {
            smartParkCarParkingExample.setOrderByClause("open_time desc");
        }
        List<SmartParkCarParking> passRecords = smartParkCarParkingMapper.selectByExample(smartParkCarParkingExample);
        long count = smartParkCarParkingMapper.countByExample(smartParkCarParkingExample);
        return ResponseBodyWrapperUtil
                .successListWrapper(passRecords, count, qo, SmartParkCarParkingVO.class);
    }

    /**
     * 新增停车记录
     * 
     * @param vo 停车记录
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResponseBody<Boolean> insertSmartParkCarParking(@Valid SmartParkCarParkingVO vo) throws Exception {
        // 验证 todo
        SmartParkCarParking smartParkCarParking = new SmartParkCarParking();
        try {
            BeanUtil.insertConversion(vo, smartParkCarParking);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCarParking.beforeInsert();
        smartParkCarParking.setOpenTime(new Date());
        //查询访客
        if(vo.getCarType()!=null && vo.getCarType()==2){
            SmartParkVisitor smartParkVisitor = smartParkVisitorMapper.selectByPrimaryKey(vo.getUserId());
            smartParkCarParking.setIdNum(smartParkVisitor.getVisitorIdNum());
            smartParkCarParking.setUserName(smartParkVisitor.getVisitorName());
            smartParkCarParking.setPhoneNum(smartParkVisitor.getVisitorPhoneNum());
            //查询员工
        }else if(vo.getCarType()!=null && vo.getCarType()==1) {
            SsoUserRpcQO ssoUserRpcQO = new SsoUserRpcQO();
            ssoUserRpcQO.setUserId(Convert.toStr(vo.getUserId()));
            ssoUserRpcQO.setNeedPage(false);
            CommonResponseBody<SsoUserDTO>  aclUserRpcServiceUser = aclUserRpcService.getUser(ssoUserRpcQO);
            if (StringUtils.isNotNull(aclUserRpcServiceUser.getData())) {
                smartParkCarParking.setIdNum(aclUserRpcServiceUser.getData().getIdCard());
                smartParkCarParking.setUserName(aclUserRpcServiceUser.getData().getRealName());
                smartParkCarParking.setPhoneNum(aclUserRpcServiceUser.getData().getPhone());
            }
        }
        //查闸道
        SmartDeviceNoAclRpcQO smartDeviceNoAclRpcQO = new SmartDeviceNoAclRpcQO();
        smartDeviceNoAclRpcQO.setDeviceCode(Convert.toStr(vo.getRoadGate()));
        CommonResponseBody<SmartDeviceDTO>  commonResponseBody = smartParkDeviceRpcService.getDeviceNoAcl(smartDeviceNoAclRpcQO);
        if(StringUtils.isNotNull(commonResponseBody.getData())){
            smartParkCarParking.setRoadGateName(commonResponseBody.getData().getDeviceName());
        }

        //摄像头
        SmartDeviceNoAclRpcQO smartDeviceNoAclRpcQOsx = new SmartDeviceNoAclRpcQO();
        smartDeviceNoAclRpcQOsx.setDeviceCode(Convert.toStr(vo.getCameraDeviceCode()));
        CommonResponseBody<SmartDeviceDTO>  commonResponseBodysx = smartParkDeviceRpcService.getDeviceNoAcl(smartDeviceNoAclRpcQOsx);
        if(StringUtils.isNotNull(commonResponseBodysx.getData())){
            smartParkCarParking.setCameraDeviceName(commonResponseBodysx.getData().getDeviceName());
        }

        //查车场名
        SmartParkArea smartParkArea = smartParkAreaMapper.selectByPrimaryKey(Convert.toLong(commonResponseBody.getData().getDeviceAreaCode()));
        if(StringUtils.isNotNull(smartParkArea)){
            smartParkCarParking.setParkName(smartParkArea.getAreaName());
        }

        try {
            //上传图片
            if(StringUtils.isNotEmpty(vo.getOpenPic())){
                SysFileDTO openPic = new SysFileDTO();
                BASE64Decoder decoder = new BASE64Decoder();
                byte[] b = decoder.decodeBuffer(vo.getOpenPic().replace("data:image/jpg;base64,", ""));
                String filename = IdUtil.objectId()+".png";

                FileUploadResponse visitorPhotoUploadResponse = minioUtil.uploadFile(b,"car-photo",filename);
                openPic.setBusiType(1);
                openPic.setFilePath(filename);
                openPic.setFileName(filename);
                openPic.setFileUrl(visitorPhotoUploadResponse.getUrlHttp());
                openPic.setFileExt("png");
                openPic.setBucketName("car-photo");
                openPic.setTenantId(vo.getTenantId());
                CommonResponseBody<SysFileDTO> dtoCommonResponseBody1 = aclFileRpcService.insertSysFile(openPic);
                openPic = dtoCommonResponseBody1.getData();
                if(StringUtils.isNotNull(openPic)){
                    smartParkCarParking.setOpenPic(Convert.toStr(openPic.getId()));
                }
            }
        }catch (Exception e){
            smartParkCarParking.setOpenPic(null);
            logger.error(e.toString());
        }


        int res = smartParkCarParkingMapper.insertSelective(smartParkCarParking);
        if(vo.getStatus()==1 && res>0){
            //查询车牌是否有停车记录
            SmartParkCarParkParkingExample smartParkCarParkParkingExample = new SmartParkCarParkParkingExample();
            SmartParkCarParkParkingExample.Criteria carParkParkingExampleCriteria = smartParkCarParkParkingExample.createCriteria();
            if (vo.getTenantId() != null) {
                carParkParkingExampleCriteria.andTenantIdEqualTo(vo.getTenantId());
            }
            carParkParkingExampleCriteria.andIsDeletedEqualTo(0);
            carParkParkingExampleCriteria.andLicensePlateEqualTo(vo.getLicensePlate());
            carParkParkingExampleCriteria.andStatusEqualTo(0);
            smartParkCarParkParkingExample.setOrderByClause("gmt_create desc");
            List<SmartParkCarParkParking> passRecords = smartParkCarParkParkingMapper.selectByExample(smartParkCarParkParkingExample);
            //先判断进场还是出场   进
            if(vo.getOpenType()==0){
                //已经有进场数据  不处理 属于重复抓拍
                if (StringUtils.isEmpty(passRecords)) {
                    SmartParkCarParkParking smartParkCarParkParking = new SmartParkCarParkParking();
                    try {
                        BeanUtil.insertConversion(smartParkCarParking, smartParkCarParkParking);
                    } catch (Exception e) {
                        logger.error("", e);
                    }
                    smartParkCarParkParking.setJoinTime(smartParkCarParking.getOpenTime());
                    smartParkCarParkParking.setJoinPic(smartParkCarParking.getOpenPic());
                    smartParkCarParkParking.setJoinRoadGate(smartParkCarParking.getRoadGate());
                    smartParkCarParkParking.setJoinRoadGateName(smartParkCarParking.getRoadGateName());
                    smartParkCarParkParking.setJoinCameraDeviceCode(smartParkCarParking.getCameraDeviceCode());
                    smartParkCarParkParking.setJoinCameraDeviceCode(smartParkCarParking.getCameraDeviceCode());
                    smartParkCarParkParking.setStatus(0);
                    smartParkCarParkParking.beforeInsert();
                    smartParkCarParkParking.setJoinTime(new Date());
                    smartParkCarParkParkingMapper.insertSelective(smartParkCarParkParking);
                }else {
                    SmartParkCarParkParking smartParkCarParkParking = passRecords.get(0);
                    smartParkCarParkParking.setJoinTime(smartParkCarParking.getOpenTime());
                    smartParkCarParkParking.setJoinPic(smartParkCarParking.getOpenPic());
                    smartParkCarParkParking.setJoinRoadGate(smartParkCarParking.getRoadGate());
                    smartParkCarParkParking.setJoinRoadGateName(smartParkCarParking.getRoadGateName());
                    smartParkCarParkParking.setJoinCameraDeviceCode(smartParkCarParking.getCameraDeviceCode());
                    smartParkCarParkParking.setJoinCameraDeviceCode(smartParkCarParking.getCameraDeviceCode());
                    smartParkCarParkParking.setStatus(0);
                    smartParkCarParkParking.beforeInsert();
                    smartParkCarParkParking.setJoinTime(new Date());
                    smartParkCarParkParkingMapper.updateByPrimaryKeySelective(smartParkCarParkParking);
                }
            // 出
            }else if(vo.getOpenType()==1) {
                //查询不到已进场数据  不处理  已经处理过 属于重复抓拍
                if(StringUtils.isNotEmpty(passRecords)){
                    SmartParkCarParkParking smartParkCarParkParking = passRecords.get(0);
                    smartParkCarParkParking.setOutTime(smartParkCarParking.getOpenTime());
                    smartParkCarParkParking.setOutRoadGate(smartParkCarParking.getRoadGate());
                    smartParkCarParkParking.setOutRoadGateName(smartParkCarParking.getRoadGateName());
                    smartParkCarParkParking.setOutCameraDeviceCode(smartParkCarParking.getCameraDeviceCode());
                    smartParkCarParkParking.setOutCameraDeviceName(smartParkCarParking.getCameraDeviceName());
                    smartParkCarParkParking.setOutPic(smartParkCarParking.getOpenPic());
                    String stopTime = DateUtil.formatBetween(smartParkCarParkParking.getJoinTime(), smartParkCarParkParking.getOutTime(), BetweenFormater.Level.MINUTE);
                    smartParkCarParkParking.setStopTime(stopTime);
                    smartParkCarParkParking.beforeUpdate();
                    smartParkCarParkParking.setStatus(1);
                    smartParkCarParkParkingMapper.updateByPrimaryKeySelective(smartParkCarParkParking);
                }
            }
        }
        return ResponseBodyWrapperUtil.success();
    }


    /**
     * 修改停车记录
     * 
     * @param vo 停车记录
     * @return 结果
     */
    @Override
    public CommonResponseBody<Boolean> updateSmartParkCarParking(@Valid SmartParkCarParkingVO vo)
    {
        if(StringUtils.isNull(vo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        // 验证 todo
        SmartParkCarParking smartParkCarParking = new SmartParkCarParking();
        try {
            BeanUtil.insertConversion(vo, smartParkCarParking);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCarParking.beforeUpdate();
        return ResponseBodyWrapperUtil.toResData(smartParkCarParkingMapper.updateByPrimaryKeySelective(smartParkCarParking));
    }

    /**
     * 删除停车记录信息
     * 
     * @param vo 停车记录
     * @return 结果08
     */
    @Override
    public CommonResponseBody<Boolean> deleteSmartParkCarParking(@Valid SmartParkCarParkingVO vo)
    {
        // 验证 todo
        if(StringUtils.isNull(vo.getId())){
            return ResponseBodyWrapperUtil.fail(ErrMsgEnum.ERROR_PARAME);
        }
        SmartParkCarParking smartParkCarParking = new SmartParkCarParking();
        try {
            BeanUtil.insertConversion(vo, smartParkCarParking);
        } catch (Exception e) {
            logger.error("", e);
        }
        smartParkCarParking.beforeDelete();
        return ResponseBodyWrapperUtil.toResData(smartParkCarParkingMapper.updateByPrimaryKeySelective(smartParkCarParking));
    }
}
